﻿/**
* CRL
*/
using CRL.Data.LambdaQuery;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace CRL.Data.DBExtend.RelationDB
{
    public sealed partial class DBExtend
    {
        #region query list

        /// <summary>
        /// 使用完整的LamadaQuery查询
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="iQuery"></param>
        /// <param name="cacheKey">cacheKey</param>
        /// <returns></returns>
        public override List<TModel> QueryOrFromCache<TModel>(ILambdaQuery<TModel> iQuery, out string cacheKey)
        {
            var query = iQuery as LambdaQueryBase;
            cacheKey = "";
            if (query.__PrefixsQuery.TryGetValue(typeof(TModel).Name, out var viewQuery))
            {
                return QueryResult<TModel>(query, viewQuery.Item2);
            }
            if (!query.__IsFromResultSelect)
            {
                CheckTableCreated<TModel>();
            }
            var list = new List<TModel>();
            var cacheTime = query.__ExpireMinute;
            if (query.PageIndex > 0 || cacheTime <= 0)
            {
                list = QueryResult<TModel>(query, null);
                return list;
            }
            cacheKey = "";
            //IDataReader reader;
            query.FillParames(this);
            var sql = query.GetQuery();
            sql = _DBAdapter.SqlFormat(sql);

            //var compileSp = query.__CompileSp && _DBAdapter.CanCompileSP;
            //double runTime = 0;
            var db = GetDBHelper(DataAccessType.Read);
            list = MemoryDataCache.CacheService.GetCacheList<TModel>(sql, query.GetFieldMapping(), cacheTime, db, out cacheKey).Values.ToList();
            //if (cacheTime <= 0)
            //{
            //    list = SqlStopWatch.ReturnList(() =>
            //    {
            //        if (!compileSp || !_DBAdapter.CanCompileSP)
            //        {
            //            reader = db.ExecDataReader(sql);
            //        }
            //        else//生成储过程
            //        {
            //            string sp = CompileSqlToSp(_DBAdapter.TemplateSp, sql);
            //            reader = db.RunDataReader(sp);
            //        }
            //        query.ExecuteTime += db.ExecuteTime;
            //        var queryInfo = new LambdaQuery.Mapping.QueryInfo<TModel>(false, query.GetQueryFieldString(), query.GetFieldMapping());
            //        var result = ObjectConvert.DataReaderToSpecifiedList(reader, queryInfo, out var includeValues);
            //        ObjectConvert.fillIncludeOneResult(result, query.__IncludeTypes, includeValues);
            //        return result;
            //    }, sql);
            //    query.MapingTime += runTime;
            //}
            //else
            //{
            //    list = MemoryDataCache.CacheService.GetCacheList<TModel>(sql, query.GetFieldMapping(), cacheTime, db, out cacheKey).Values.ToList();
            //}
            ClearParame();
            query.__RowCount = list.Count;
            //query = null;
            return list;
        }


        #endregion



        public override TType GetFunction<TType, TModel>(Expression<Func<TModel, bool>> expression, Expression<Func<TModel, TType>> selectField, FunctionType functionType, bool compileSp = false)
        {
            LambdaQuery<TModel> query = new RelationLambdaQuery<TModel>(dbContext, true);
            query.Select(selectField.Body);
            query.__FieldFunctionFormat = string.Format("{0}({1}) as _total", functionType, "{0}");
            if (expression != null)
            {
                query.Where(expression);
            }
            var result = QueryScalar(query);
            if (result == null || result is DBNull)
            {
                return default(TType);
            }
            return (TType)result;
        }

        //public override Dictionary<TKey, TValue> ToDictionary<TModel, TKey, TValue>(ILambdaQuery<TModel> query)
        //{
        //    var dic = SqlStopWatch.ReturnData(() =>
        //      {
        //          return GetQueryDynamicReader(query as LambdaQueryBase);

        //      }, (r) =>
        //      {
        //          return ObjectConvert.DataReadToDictionary<TKey, TValue>(r.reader);
        //      });
        //    return dic;
        //}

    }
}
